home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 3
/
Gold Medal Software - Volume 3 (Gold Medal) (1994).iso
/
prog
/
oalrs100.arj
/
80X86S.TXT
< prev
next >
Wrap
Text File
|
1994-05-04
|
89KB
|
1,641 lines
Credits and Ordering Information.
This text file is an excerpt from "The 80x86 Online Assembly Language
Reference", an Expert Help database that documents the instructions and
architecture of the 80x86 family of processors. The complete reference is
accessed using Expert Help, a hypertext TSR available from SofSolutions,
Inc. This file was created to provide the reader with an impression of
the contents of the reference. However, it does not suggest the ease at
which the information can be found in the online reference or the
convenience of having the information available from a TSR.
This excerpt was written by Todd Niec at Ware Unlimited, Inc.
Copyright (c) 1992, 1993, 1994. This excerpt may be freely distributed in
its original form, but may not be altered or sold for any reason without
the express permission of the copyright holders.
This file contains a sample of part of the 80x86 OnLine Assembly
Language Reference distributed by Ware, Inc. The complete reference has
the following features:
Documentation of all the 80x86 instructions and prefixes
(247 entries) through the 80586 processor, including some little known
unofficial instructions that Intel does not usually document.
Entries for 6 instructions available only on 80x86 processors.
Entries for 5 instructions available only on 80486 and latter
processors.
Entries for 78 instructions available only on 80386 and latter
processors.
Entries for 2 instructions available only on 80386 processors.
Over 18,000 lines of documentation.
The instructions can be found in an alphabetical list or in lists
that groups instructions by their function.
Each instruction is carefully documented and includes information on
instruction timing, encoding, assembler syntax, and algorithms.
Many entries contain programming tips and examples.
An overview of the design and features of the 80x86 family of
processors.
A section on instruction encoding.
A description of the 80x86 addressing modes.
An explanation of timing issues that effect the performance of each
processor.
Techniques for optimizing assembly code.
Whether you're a full-time assembly language programmer, or just
interested in speeding up a bottle-neck with a few lines of assembly code
the 80x86 OnLine Assembly Language Reference is an absolute must.
Each copy of the database is only $29.95 plus $3 Shipping and handling.
(when available, 2nd Day shipping is $5 and next day shipping is $10).
Visa and Mastercard are accepted.
To obtain a copy of the complete 80x86 Online Assembly Language
Reference, contact Ware Unlimited at (717) 898-7911 or print and mail/FAX
the order form that appears below.
──────────────────────────────────────────────────────────────────────────────
80X86 ONLINE ASSEMBLY LANGUAGE REFERENCE ORDER FORM
Ware Unlimited, Inc.
195 Broad Street
Salunga PA, 17538
(717) 898-7911
FAX: (717) 898-9107
Please send me ___ copies of the 80x86 Online Assembly Language Reference
at $29.95 each (plus shipping and handling).
Ship: ___ Surface ($3 each) ___ 2nd Day ($5 each) ___ Next Day ($10)
(2nd day and next day only when available.)
Total Amount: $____.__
Ship To: __________________________________
__________________________________
__________________________________
__________________________________
Phone: (____) ____ - ______
Payment Method: ___ Master Card ___ Visa ___ Personal Check
Card Number: __|__|__|__ __|__|__|__ __|__|__|__ __|__|__|__
Expiration Date: ___/19___
Signature: ______________________________
───────────────────────────────────────────────────────────────────────────────
AAA ASCII Adjust after Addition Flags: O D I T S Z A P C
? ? ? * ? *
SYNTAX:
AAA
LOGIC:
IF (AL && 0FH) > 09H OR (AF = 1) THEN
AL (AL + 6) && 0FH
AH (AH + 1) && 0FH
AF 1
CF 1
ELSE
AL AL && 0FH
AF 0
CF 0
ENDIF
This instruction is used to convert the result of adding two unpacked
BCD digits with the ADD instruction to the proper unpacked BCD digit.
This instruction is necessary because when two unpacked BCD digits are
added (values from 0 to 9) they produce results from 0 to 18 (19 if ADC
was used). However, the values above 9 are not valid unpacked BCD values
because in decimal notation they must be expressed as two digits. These
values occur when there should have been a decimal carry from the digits
added to the next (more significant) digits. In these cases AAA will
convert the result to the proper second digit and add one (a carry) to the
value in AH.
This instruction is usually used in multi-digit additions. To use the
instruction in this way, one of the next digits to be added is stored in
AH when the AAA is performed, this will add the carry of the current digit
to the next. For example:
ADDTOP: MOV AH,[DI] ; Get next destination digit.
MOV BH,[SI] ; Get next source digit.
ADD AL,BL ; Add current digits.
AAA ; Convert result to BCD.
MOV [DI]-1,AL ; Store result in destination operand.
MOV AL,AH ; Get new destination digit.
MOV BL,BH ; Get new source digit.
DEC DI ; Point to next destination digit
DEC SI ; Point to next source digit
LOOP ADDTOP ; Loop back to add next digit.
Since the AAA instruction also sets the carry flag when there should
be a carry from the current digit to the next, it is possible to ignore
the value in AH and add digits with the ADC instruction. For example:
ADDTOP: MOV AL,[DI] ; Get current destination digit.
MOV BL,[SI] ; Get current source digit.
ADC AL,BL ; Add current digits.
AAA ; Convert result to BCD.
MOV [DI],AL ; Store result in destination operand.
DEC DI ; Point to next destination digit
DEC SI ; Point to next source digit
LOOP ADDTOP ; Loop back to add next digit.
Since this operation ignores the high nibble of AL and clears the
high nibbles of AL and AH, the instruction will also convert the result of
adding two ASCII numbers, that is the ASCII characters representing
digits. However, the converted result will be in unpacked BCD, not in
ASCII.
┌────────────────────────────────────────────────────────────────────────┐
│ 0011 0111 │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ AAA │ AAA │ 88/86 8 │
│ │ │ 286 3 │
│ │ │ 386 4 │
│ │ │ 486 3 │
│ │ │ Pentm 3 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
ADC Add with Carry Flags: O D I T S Z A P C
* * * * * *
SYNTAX:
ADC destination,source
LOGIC:
IF CF = 1 THEN
destination destination + source + 1
ELSE
destination destination + source
ENDIF
This instruction adds together the two operands and the value of the
carry flag and stores the result in the destination operand. This is
usually used to perform "multi-element addition" in order to add
quantities that are larger than the largest operand supported by the
processor.
In multi-element addition, the quantities are added using multiple
add operations that start with the least significant portion (byte, word
or doubleword) of the quantities and proceed to the most significant
portion. The first addition is performed with a regular ADD instruction
(or ADC if the carry flag is previously cleared) and the remaining
additions use the ADC instruction.
Note: The quantities to be added can be either signed or unsigned.
EXAMPLE
This example adds the 32 bit number in DX:AX to the 32 bit number in
CX:BX and stores the result in DX:AX.
ADD AX,BX ; Add least significant word.
ADC DX,CX ; Add most significant word with carry.
This example performs a multi-element add of two operands specified
by pointers in SI and DI and whose length is specified in CX. This
example relies on the fact that when SI is adjusted with an INC
instruction, the carry flag is not affected. This is probably the main
reason that INC and DEC do not update the carry flag.
CLC ; Clear carry for first add.
ADDTOP: MOV AL,[DI] ; Get next destination byte.
ADC AL,[SI] ; Add on next source byte.
STOSB ; Store result
INC SI ; Point to next source byte.
LOOP ADDTOP ; Loop back for next byte, if any.
┌────────────────────────────────────────────────────────────────────────┐
│ 0001 00,d,w mod,reg,r/m 0, 2, or 4 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ ADC reg,reg │ ADC DX,CX │ 88/86 3 │
│ │ │ 286 2 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ ADC mem,reg │ ADC NUMBER,CL │ 88/86 16+EA │
│ │ │ WD88 24+EA │
│ │ │ 286 7 │
│ │ │ 386 7 │
│ │ │ 486 3 │
│ │ │ Pentm 3 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ ADC reg,mem │ ADC CL,NUMBER │ 88/86 9+EA │
│ │ │ WD88 13+EA │
│ │ │ 286 7 │
│ │ │ 386 6 │
│ │ │ 486 2 │
│ │ │ Pentm 2 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 1000 00,s,w mod,010,r/m 0, 2, or 4 byte displacement │
│ 1, 2, or 4 byte immediate data │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ ADC reg,immed │ ADC BX,1992 │ 88/86 4 │
│ │ │ 286 3 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ ADC mem,immed │ ADC NUMBER,DX │ 88/86 17+EA │
│ │ │ WD88 23+EA │
│ │ │ 286 7 │
│ │ │ 386 7 │
│ │ │ 486 3 │
│ │ │ Pentm 3 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 0001 010,w 1, 2, or 4 byte immediate data │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ ADC accum,immed │ ADC AX,1992 │ 88/86 4 │
│ │ │ 286 3 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
BTC Bit Test and Complement Flags: O D I T S Z A P C
*
SYNTAX:
BTC source,bitnum
LOGIC:
CF BIT(bitnum,source)
BIT(bitnum,source) NOT BIT(bitnum,source)
This instruction copies the bit specified by bitnum from the source
operand to the carry flag, then complements (inverts) the specified bit.
That is, the carry flag is set if the specified bit is set, otherwise it
is cleared and then the specified bit is switched to its other value. Bits
in an operand are numbered from zero starting with the low (least
significant) bit.
Since the destination can be either 16 or 32 bits, one would expect
bitnum to contain only values from 0 to 15 or 0 to 31. Actually, the
instruction can handle larger bit numbers. If the bit number is an
immediate (byte) value, or the destination is a register, then the bit
tested is the bit number modulo the number of bits in the destination
operand. For example,
BTC AX,16
will test bit 1, since 16 MOD 16 is 1. However, if the destination is a
memory location and the bit number is in a register, then the instruction
will treat the memory location as a 2^16 (or 2^32) bit operand and will
test the appropriate bit in one of the successive words (or doublewords).
In this case, the bit number operand can be considered to contain two
fields. One specifies the bit to be tested. The other specifies a
displacement from the destination to the memory location to be tested.
The field specifying the bit to be tested occupies the low 4 bits for a
word destination and 5 bits for a double word destination. The
displacement occupies rest of the field. The memory location tested is
the specified effective address plus an additional displacement calculated
from
2*(bitnum DIV 16)
for a word operand or
4*(bitnum DIV 32)
for a doubleword operand. Thus the instructions
MOV AX,00010011Y
MOV BX,100H ; Get pointer to 100H.
BTC WPTR [BX],AX
will test bit 3 of the word at address 102H, because the low 4 bits
contain a 3 and the high 12 bits contain a 1.
This function is available only on 80386 and later processors.
┌────────────────────────────────────────────────────────────────────────┐
│ 0000 1111 1011 1011 mod,reg,r/m 0, 2, or 4 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ BTC reg16,reg16 │ BTC AX,CX │ 88/86 N/A │
│ BTC reg32,reg32 │ BTC EAX,ECX │ 286 N/A │
│ │ │ 386 6 │
│ │ │ 486 6 │
│ │ │ Pentm 7 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ BTC mem16,reg16 │ BTC BIFFLD,AX │ 88/86 N/A │
│ BTC mem32,reg32 │ BTC BITFLD,EAX │ 286 N/A │
│ │ │ 386 13 │
│ │ │ 486 13 │
│ │ │ Pentm 13 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 0000 1111 1011 1010 mod,111,r/m 0, 2, or 4 byte displacement │
│ 1 byte immediate data │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ BTC reg16,immed8 │ BTC AX,3 │ 88/86 N/A │
│ BTC reg32,immed8 │ BTC EAX,3 │ 286 N/A │
│ │ │ 386 6 │
│ │ │ 486 6 │
│ │ │ Pentm 7 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ BTC mem16,immed8 │ BTC BIFFLD,4 │ 88/86 N/A │
│ BTC mem32,immed8 │ BTC BITFLD,4 │ 286 N/A │
│ │ │ 386 8 │
│ │ │ 486 8 │
│ │ │ Pentm 8 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
CMPSB Compare String Byte Flags: O D I T S Z A P C
* * * * * *
SYNTAX:
CMPSB
LOGIC:
Flags set according to result of mem8[DS:SI] - mem8[ES:DI]
IF DF = 0 THEN
SI SI + 1
DI DI + 1
ELSE
SI SI - 1
DI DI - 1
ENDIF
This instruction compares two memory locations by setting the flags
as if the byte at [ES:DI] were subtracted from the byte at [DS:SI].
Neither memory location is altered by this operation. The destination
operand must be in the extra segment (ES), and the source should be in the
data segment (DS) unless the instruction is proceeded by a segment
override. Following the comparison, SI and DI are incremented (or
decremented if the direction flag is set) by 1, in preparation for testing
the next (or previous) memory locations.
The conditional repeat prefixes may be used to compare two memory
buffers. This is used to determine whether or not two memory buffers are
identical. It can also be used to locate where the buffers are same or
where they are different.
EXAMPLE:
The following example determines the first memory locations where two
buffers are different.
CLD ; Increment string pointers.
MOV SI,OFFSET BUF1 ; Get pointer to 1st buffer.
MOV DI,OFFSET BUF2 ; Get pointer to 2nd buffer.
MOV CX,BUFLEN ; Load counter with length of buffers.
REPZ CMPSB ; Look for 1st mismatch.
JZ IDENTICAL ; Abort if buffers are identical.
DEC SI ; Point back to first bytes that
DEC DI ; were different.
* * *
The following example determines the last memory locations where two
buffers are the same.
STD ; Decrement string pointers.
MOV SI,OFFSET BUF1+BUFLEN-1 ; Point to end of 1st buffer.
MOV DI,OFFSET BUF2+BUFLEN-1 ; Point to end of 2nd buffer.
REPNZ CMPSB ; Look for 1st match.
JNZ DIFFERENT ; Abort, if completely different.
INC SI ; Point back to first bytes
INC DI ; that were the same.
* * *
┌────────────────────────────────────────────────────────────────────────┐
│ 1010 0010 │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ CMPSB │ CMPSB │ 88/86 22 │
│ │ │ 286 8 │
│ │ │ 386 10 │
│ │ │ 486 8 │
│ │ │ Pentm 5 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ REPZ CMPSB │ REPZ CMPSB │ 88/86 9+22n │
│ │ │ 286 5+9n │
│ │ │ 386 5+9n │
│ │ │ 486 7+7n 5 when n=0 │
│ │ │ Pentm 9+4n 7 when n=0 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ REPNZ CMPSB │ REPNZ CMPSB │ 88/86 9+22n │
│ │ │ 286 5+9n │
│ │ │ 386 5+9n │
│ │ │ 486 7+7n 5 when n=0 │
│ │ │ Pentm 8+4n 7 when n=0 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
CPUID Identify Processor Flags: O D I T S Z A P C
SYNTAX:
CPUID
LOGIC:
IF EAX > MAX_CPUID_FCT THEN
EAX undefined.
EBX undefined.
ECX undefined.
EDX undefined.
ELSEIF EAX = 0 THEN
EAX MAX_CPUID_FCT
EBX Vendor identification string characters 1-4.
ECX Vendor identification string characters 5-8.
EDX Vendor identification string characters 9-12.
ELSEIF EAX = 1 THEN
EAX Processor ID.
EBX Reserved.
ECX Reserved.
EDX Feature flags.
ELSE
No other cases possible on chips up to the Pentium. But other
processors and manufacturers will support additional function numbers.
ENDIF
This instruction is used to determine the make, model, family, and
features of a processor. Unfortunately, this instruction is supported
only on 586 and later processors. This instruction will probably provide
additional information on future processors. When the instruction is
performed, EAX contains a function number that identifies the type of
information to be returned. Currently only two function numbers (0 and 1)
are supported, but future processors are expected to support more. To
insure backward compatibility, function 0 returns the maximum function
number recognized by the processor, thus a program can avoid using
invalid function numbers.
When the function zero is executed, EAX returns the highest function
number supported. EBX:ECX:EDX returns a 12 character ASCII string
identifying the processor's manufacturer. The first digit of the 4 digit
sub-strings is stored in the low byte. Thus, if the registers are stored
in memory as doublewords, the appropriate name is formed. For example.
MOV CPUMAKNAM,EBX
MOV CPUMAKNAM+4,ECX
MOV CPUMAKNAM+8,EDX
* * *
CPUMAKNAM DD 0,0,0
The pentium processor and other Intel chips will return
EBX = 756E6547H
ECX = 49656E69H
EDX = 6C65746EH
which forms "GenuineIntel".
When function one is executed. EAX returns information that
identifies the model of the processor. The low four bytes are the
stepping ID of the processor. From intel's documentation, I have inferred
that the processor's step is indicated in BCD. Thus the A stepping is
indicated by a 0AH, the B stepping by a 0BH. The next four bits specify
the model (for example, if is the processor an SX or DX chip). These bits
appear to be interpreted as a binary number with the first model numbered
as 1. The next four bits, specify the processor's family. A 586 chip
returns a binary 5 in these bits and a 686 chip will, presumably, return a
a 6. The remainder of EAX is reserved.
31 12 11 8 7 4 3 0
┌───────────────────┬────┬────┬────┐
│Reserved │Fmly│Modl│Step│
└───────────────────┴─┬──┴─┬──┴─┬──┘
│ │ └─── Stepping ID.
│ └──────── Model.
└───────────── Family.
When function one is executed, EDX returns information that
identifies the processor's features. If bit 0 is set, the chip contains a
built-in floating point unit. Bit 7 indicates if the processor supports
the machine check exception. If bit 8 is set, the processor supports the
CMPXCHG8B instruction. The remaining bits are either reserved or their
interpretation is considered proprietary of Intel inc. and may not be
disclosed to the public.
┌────────────────────────────────────────────────────────────────────────┐
│ 0000 1111 1010 0010 │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ CPUID │ CPUID │ 88/86 N/A │
│ │ │ 286 N/A │
│ │ │ 386 N/A │
│ │ │ 486 N/A │
│ │ │ Pentm 14 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
'───────────────────────────────────────────────────────────────────────────────
DEC Decrement Flags: O D I T S Z A P C
* * * * *
SYNTAX:
DEC destination
LOGIC:
destination destination - 1
This instruction decrements the destination operand by one. This
instruction is usually preferable to subtracting one from an operand with
the SUB instruction because it is shorter.
Note that, unlike the SUB instruction, this instruction does not
affect the carry flag. This allows the instruction to be used to
decrement pointers without affecting the carry in multi-element arithmetic
routines.
┌────────────────────────────────────────────────────────────────────────┐
│ 1111 111,w mod,001,r/m 0, 2, or 4 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ DEC reg8 │ DEC BL │ 88/86 3 │
│ │ │ 286 2 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ DEC mem │ DEC COUNT │ 88/86 15+EA │
│ │ │ WD88 23+EA │
│ │ │ 286 7 │
│ │ │ 386 6 │
│ │ │ 486 3 │
│ │ │ Pentm 3 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 0100 1,reg │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ DEC reg16 │ DEC AX,NUMBER │ 88/86 3 │
│ DEC reg32 │ DEC ECX │ 286 2 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
'───────────────────────────────────────────────────────────────────────────────
ENTER High Level Procedure Enter Flags: O D I T S Z A P C
SYNTAX:
ENTER localsize,nesting
LOGIC:
IF operandsize = 16 BIT THEN
PUSH(BP)
saveptr BP
FOR i = 1 TO nesting DO
BP BP - 2
PUSH([BP])
ENDFOR
PUSH(saveptr)
BP saveptr
SP SP - localsize
ELSE
PUSH(EBP)
saveptr EBP
FOR i = 1 TO nesting DO
EBP EBP - 4
PUSH([EBP])
ENDFOR
PUSH(saveptr)
EBP saveptr
ESP ESP - localsize
ENDIF
This instruction can be used to create a stack frame. The first
operand is the size of the local variables (in bytes) to be allocated on
the stack. The second parameter is the number of stack frame pointers
from the nested calling routines that the procedure will need (or any
procedure it calls will need).
The instruction works as follows, BP is pushed to save the stack
frame of the calling procedure. Then the routine copies the specified
number of stack frame pointers from the calling procedure. It assumes
that the stack frame pointers were allocated in the calling procedure at
the first negative offsets from the base pointer and it allocates them in
the new procedure at the first negative offsets from the base pointer.
Next it pushes a copy of the new stack frame pointer (so that any
sub-routines called can get this routine's stack frame pointer. Finally
it decrements the stack pointer by size of the local variables to be
allocated.
The stack frame looks like this.
Offset Length
┌──────────────────┐
Low │ Local Variables. │ [BP] -2*nesting-4 localsize
│ │ [EBP]-4*nesting-8 localsize
│ ├──────────────────┤
│ │ Saved Current │ [BP] -2*nesting-2 2
│ │ Frame pointer. │ [EBP]-4*nesting-4 4
│ ├──────────────────┤
│ │ Calling Routines'│ [BP] +0 2*nesting
│ │ Frame Pointers. │ [EBP]+0 4*nesting
│ ├──────────────────┤
│ │ Saved Previous │ [BP] +2 2
│ │ Frame Pointer. │ [EBP]+4 4
│ ├──────────────────┤
│ │ Address to be │ [BP] +4 2 or 4
│ │ RETurned to. │ [EBP]+8 2 or 4
│ ├──────────────────┤
│ Parameters to │ [BP] +6 or +8 Set by caller
High │ Current Routine. │ [EBP]+10 or +12 Set by caller
└──────────────────┘
After the instruction, the stack frame pointer BP, points to the
previous routine's saved stack frame pointer. At negative offsets from BP
there are the stack frame pointers of the calling routines, which can be
used to access the local variables of the calling routines. The highest
routine's stack frame pointer is at [BP]-2 and the calling routine's
pointer is at [BP]-2*nesting (in 16 bit mode). The local variables, if
any are allocated, start at [BP]-2*nesting-2. The address of the calling
routine's instruction to RET is at [BP]+2. Then at [BP]+4 (or at [BP]+6
if this is a FAR routine) there are the parameters placed on the stack by
the calling routine.
In timings with a nesting value greater than 1, n represents the
nesting level.
┌────────────────────────────────────────────────────────────────────────┐
│ 1100 1000 2 byte localsize 1 byte nesting │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ ENTER immed16,0 │ ENTER 6,0 │ 88/86 N/A │
│ │ │ 286 11 │
│ │ │ 386 10 │
│ │ │ 486 14 │
│ │ │ Pentm 11 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ ENTER immed16,1 │ ENTER 4,1 │ 88/86 N/A │
│ │ │ 286 15 │
│ │ │ 386 12 │
│ │ │ 486 17 │
│ │ │ Pentm 15 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ ENTER immed16,immed8│ ENTER 10,4 │ 88/86 N/A │
│ │ │ 286 16+4*(n-1) │
│ │ │ 386 15+4*(n-1) │
│ │ │ 486 17+3*n │
│ │ │ Pentm 15+2*n │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
INVD Invalidate a Page in the TLB Flags: O D I T S Z A P C
SYNTAX:
INVLPG destination
LOGIC:
Invalidate the Translation Lookaside Buffer entries for the specified
linear address, if any entries exists.
This instruction is used to invalidate the Translation Lookaside
Buffer (TLB) entries for the page that the specified memory address
resides in. The TLB stores the linear address to physical address
mappings of some of the more recent pages accessed. When the processor
needs to access memory in a page that has an entry in TLB the processor
can quickly determine the physical address without having to look-up
information in the page directories and page tables. However if a page
mapping is altered, for example if a page is swapped out or moved to a new
location, the page's entry in TLB (if there is one) will not be updated
even though the page table entry (in memory) is updated. This instruction
is used to invalidate any entries in the TLB for the remapped page. Thus,
when the processor next attempts to access the page, it will not be in the
TLB and the processor will be forced to find the information using the new
information in the page directory and page tables.
The operand to INVLPG must be a linear memory address. The
instruction encoding would suggest a register operand could be specified.
However, registers don't reside in page's, thus this instruction makes no
sense with a register operand. An invalid opcode exception will occur if
the processor encounters this instruction with a register operand
specified.
This instruction is intended to be used only by the operating system.
The paging mechanism is transparent to application programs (except for
cases where an application must implement paging because the operating
system does not).
The current privilege level (CPL) must be 0 or this instruction will
cause a general protection fault.
In the timings listed below, the NH timings are for when no entries
for the page are found in the TLB.
┌────────────────────────────────────────────────────────────────────────┐
│ 0000 1111 0000 0001 mod,111,r/m │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ INVLPG │ INVLPG │ 88 N/A │
│ │ │ 86 N/A │
│ │ │ 286 N/A │
│ │ │ 386 N/A │
│ │ │ 486 12 NH=11 │
│ │ │ Pentm 25 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
JA Jump If Above Flags: O D I T S Z A P C
SYNTAX:
JA label
LOGIC:
IF (CF = 0) AND (ZF = 0) THEN
IF addresssize = 16 BIT THEN
IF shortjump THEN
IP IP + SIGNEXTEND(disp8)
ELSE
IP IP + disp16
ENDIF
ELSE
IF shortjump THEN
EIP EIP + SIGNEXTEND(disp8)
ELSE
EIP EIP + disp32
ENDIF
ENDIF
ENDIF
This instruction tests if the carry flag and zero flag are both
clear. If so, control is transferred to the instruction at the specified
label, otherwise the processor continues with the next instruction.
This instruction is usually used to test the flags set by a CMP or
SUB of two unsigned numbers. It will transfer control to the specified
label if the destination operand was above (greater than) the source
operand.
JNBE is an alternate mnemonic for the same instruction.
This instruction should be used after unsigned numbers are tested.
The corresponding mnemonic for signed numbers is JG.
┌────────────────────────────────────────────────────────────────────────┐
│ 0111 0111 1 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ JA short label │ JA ABORT │ 88 16 NJ=4 │
│ │ │ 86 16 NJ=4 │
│ │ │ 286 7+m NJ=3 │
│ │ │ 386 7+m NJ=3 │
│ │ │ 486 3 NJ=1 │
│ │ │ Pentm 1 NJ=1 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 0000 1111 1000 0111 2 or 4 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ JA near label │ JA PRGEND │ 88 N/A │
│ │ │ 86 N/A │
│ │ │ 286 N/A │
│ │ │ 386 7+m NJ=3 │
│ │ │ 486 3 NJ=1 │
│ │ │ Pentm 1 NJ=1 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
LEA Load Effective Address Flags: O D I T S Z A P C
SYNTAX:
LEA dstreg,address
LOGIC:
dstreg EA
This instruction loads a 16 or 32 bit register with an effective
address value. This is usually used to convert an effective address
involving two or more elements, like a base and index register, to an
simple address contained in only one register. For example, the code
LEA SI,[BX+SI]+100
loads into SI, the address specified by [BX+SI]+100, that is, it adds BX,
SI, and 100 stores the result in SI. This instruction can be used on
simpler effective addresses, like those involving only a pointer register
or a memory location however, it is usually not necessary to use LEA in
these case. In fact some assemblers will look for such cases and output
faster or shorter instructions that produce the same result. For example,
LEA DI,[SI]
can simply be coded as
MOV DI,SI
and
LEA AX,COUNT
. . .
COUNT DW 0
can simply be coded as
MOV AX,OFFSET COUNT
Although it is not intended to do so, this instruction can be used in
certain cases to take short cuts in arithmetic calculations. For example,
it can be used to add BX and SI and store the result in AX in one
instruction, like
LEA AX,[BX+SI]
rather than the standard two instructions
MOV AX,BX
ADD AX,SI
Note that this type of optimization can only be used when the flags do not
need to be set from the result.
Note also that the timing for this instruction on a 80486 is 1 clock
cycle unless an index register is used, in which case an extra clock cycle
may be required.
┌────────────────────────────────────────────────────────────────────────┐
│ 1000 1101 mod,reg,r/m 0, 2, or 4 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ LEA reg16,mem │ LEA AX,[BX+4] │ 88/86 2+EA │
│ │ │ 286 3 │
│ │ │ 386 2 │
│ │ │ 486 1 or 2 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ LEA reg32,mem │ LEA EBX,[BX+SI]+TBLLEN │ 88/86 N/A │
│ │ │ 286 N/A │
│ │ │ 386 2 │
│ │ │ 486 1 or 2 │
│ │ │ Pentm 1 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
MOVSX Move With Sign-Extend Flags: O D I T S Z A P C
SYNTAX:
MOVSX destination,source
LOGIC:
destination SIGNEXTEND(source)
This instruction is used to load a register with a value from memory
or another register whose size is smaller than the register to be loaded.
That is, it can be used to load a byte value into a word or doubleword
register or load a word value into a doubleword. This instruction will
treat the value to be loaded as a signed number and sign extend it to the
size of the register to be loaded. This same function can be accomplished
by loading the value into a smaller register and using the sign extension
instructions. However, the move with sign extend instruction will
generate shorter, faster code and is more flexible in register usage than
the sign extension instructions.
If the value to be loaded is not signed, the move with zero extend
instruction (MOVZX) should be used instead.
┌────────────────────────────────────────────────────────────────────────┐
│ 0000 1111 1011 111,w mod,reg,r/m 0, 2, or 4, byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ MOVSX reg,reg │ MOVSX CX,AL │ 88/86 N/A │
│ │ │ 286 N/A │
│ │ │ 386 3 │
│ │ │ 486 3 │
│ │ │ Pentm 3 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ MOVSX reg,mem │ MOVSX EAX,BYTE PTR [BX]│ 88/86 N/A │
│ │ │ 286 N/A │
│ │ │ 386 6 │
│ │ │ 486 3 │
│ │ │ Pentm 3 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
NOP No Operation Flags: O D I T S Z A P C
SYNTAX:
NOP
LOGIC:
IF operandsize = 16 bit THEN
AX AX
ELSE
EAX EAX
ENDIF
This instruction makes no effective changes to the processor's
internal state (registers or flags) except that the instruction pointer is
updated to point to the next instruction. The instruction is usually used
for two purposes. First, when debugging, it can be used to overwrite
instructions, effectively removing them from the code. Second, when the
assembler is instructed to align an instruction to a particular boundary,
it will use NOPs to provide padding after a previous instruction.
There is no actual NOP instruction, the NOP mnemonic is usually
coded as XCHG AX,AX, which is a one byte instruction that causes no
effective change to the processor. Most debuggers will display the NOP
mnemonic when they disassemble XCHG AX,AX, regardless of which instruction
was specified in the source code.
When the assembler aligns instructions, it may use instructions
other than XCHG AX,AX to minimize the padding's execution time. For
example, the assembler could code XCHG BX,BX to provide two bytes of
padding that would execute in less time than two XCHG AX,AX instructions.
Intel recommends the following methods of coding NOPs longer than one byte
and that will execute in only one clock cycle. Of course it may be
necessary to use more than one instruction to provide padding to certain
lengths.
MOV REG,REG ; 2 bytes. The source and destination must be the same.
LEA REG,[REG] ; 3 bytes. The source and destination must be the same.
LEA EAX,[EAX] ; 6 bytes. On a 386 or later.
Note that in the table below, the timing for the 486 is for the B and
later steppings of the processor. The A-Step processors require 3 clock
cycles.
┌────────────────────────────────────────────────────────────────────────┐
│ 1001 0000 │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ NOP │ NOP │ 88/86 3 │
│ │ │ 286 3 │
│ │ │ 386 3 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
OR Bitwise Logical OR Flags: O D I T S Z A P C
0 * * ? * 0
SYNTAX:
OR destination,source
LOGIC:
destination destination || source
┌────────────────────────┐
│ OR Logic Truth Table │
├────────────────────────┤
│ p q p || q │
╞════════════════════════╡
│ 0 0 0 │
│ 0 1 1 │
│ 1 0 1 │
│ 1 1 1 │
└────────────────────────┘
This instruction takes the bitwise logical OR of the source and
destination values and stores the result in the destination operand. Each
bit of the result is set if the corresponding bits of either or both
operands were set, otherwise the bit is cleared.
This instruction is often used to set specific bits in a bit field
value while leaving the remaining bits unchanged. The bit field value is
ORed with a mask that has the bits to be set, set and the bits to be left
alone cleared.
This instruction can also be used to test if a register is zero.
ORing a register with itself will set the zero flag if the register is
zero and will leave the register unchanged. This yields shorter code than
comparing (CMP) the register with zero and, on some processors, this is
faster as well. Note that this can only be used to test whether or not a
register is zero. Since the carry and overflow flags are always cleared,
it cannot be used to test if a register is greater than or less than
zero.
┌────────────────────────────────────────────────────────────────────────┐
│ 0000 10,d,w mod,reg,r/m 0, 2, or 4 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ OR reg,reg │ OR AX,BX │ 88/86 3 │
│ │ │ 286 2 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ OR reg,mem │ OR DX,BITMSK │ 88/86 16+EA │
│ │ │ WD88 24+EA │
│ │ │ 286 7 │
│ │ │ 386 6 │
│ │ │ 486 3 │
│ │ │ Pentm 2 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ OR mem,reg │ OR BITFLD,EAX │ 88/86 16+EA │
│ │ │ WD88 24+EA │
│ │ │ 286 7 │
│ │ │ 386 6 │
│ │ │ 486 3 │
│ │ │ Pentm 3 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 1000 00,s,w mod,001,r/m 0, 2, or 4 byte displacement 1, 2, 4 │
│ 1, 2, or 4 byte immediate data │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ OR reg,immed │ OR AX,0FH │ 88/86 4 │
│ │ │ 286 3 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ OR mem,immed │ OR [BX],10101010B │ 88/86 17+EA │
│ │ │ WD88 25+EA │
│ │ │ 286 7 │
│ │ │ 386 7 │
│ │ │ 486 3 │
│ │ │ Pentm 3 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
PUSH Push Value onto Stack Flags: O D I T S Z A P C
SYNTAX:
PUSH source
LOGIC:
IF stackaddrsize = 16 BIT THEN
SP SP - SIZEOF(source)
IF SIZEOF(source) = 2 THEN
mem16[SS:SP] source
ELSE
mem32[SS:SP] source
ENDIF
ELSE
ESP ESP - SIZEOF(source)
IF SIZEOF(source) = 2 THEN
mem16[SS:ESP] source
ELSE
mem32[SS:ESP] source
ENDIF
ENDIF
This instruction is used to push a word or doubleword value onto the
top of the stack. The value to be pushed may come from a register or
memory or may be immediate.
Note that some processors in the 80x86 family adjust the stack
pointer register before pushing the source and others push the source
value and then adjust the stack pointer. This difference is noticeable
only when performing an operation like PUSH SP. Since there is never a
need to save the stack pointer on the stack, the difference is of little
importance. However, this difference is often used to help determine
which processor a program is running on.
Note that PUSH reg can be coded two ways, however, the PUSH mem/reg
encoding is one byte longer, so it is not usually used to push registers.
┌────────────────────────────────────────────────────────────────────────┐
│ 0101 0,reg │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ PUSH reg16 │ PUSH AX │ 86 11 │
│ │ │ 88 15 │
│ │ │ 286 3 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ PUSH reg32 │ PUSH EBX │ 88/86 N/A │
│ │ │ 286 N/A │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 1111 1111 mod,110,r/m 0, 2, or 4 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ PUSH reg16 │ PUSH AX │ 86 11 │
│ │ │ 88 15 │
│ │ │ 286 3 │
│ │ │ 386 5 │
│ │ │ 486 4 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ PUSH reg32 │ PUSH ECX │ 88/86 N/A │
│ │ │ 286 N/A │
│ │ │ 386 5 │
│ │ │ 486 4 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ PUSH mem16 │ PUSH WORD PTR [BX] │ 86 16+EA │
│ │ │ 88 24+EA │
│ │ │ 286 5 │
│ │ │ 386 5 │
│ │ │ 486 4 │
│ │ │ Pentm 2 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ PUSH mem32 │ PUSH COUNTER │ 88/86 N/A │
│ │ │ 286 N/A │
│ │ │ 386 5 │
│ │ │ 486 4 │
│ │ │ Pentm 2 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 00,sreg,110 │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ PUSH sreg │ PUSH DS │ 86 10 │
│ │ PUSH ES │ 88 14 │
│ │ PUSH SS │ 286 3 │
│ │ PUSH CS │ 386 2 │
│ │ │ 486 3 │
│ │ │ Pentm 1 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 0000 1111 10,sreg,001 │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ PUSH sreg │ PUSH FS │ 88/86 N/A │
│ │ PUSH GS │ 286 N/A │
│ │ │ 386 2 │
│ │ │ 486 3 │
│ │ │ Pentm 1 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
ROL Rotate Left Flags: O D I T S Z A P C
* *
SYNTAX:
ROL destination,count
LOGIC:
IF Processor() = 8086 OR Processor() = 8088 THEN
n count
ELSE
n count MOD 32
ENDIF
WHILE n > 0
CF BIT(8*SIZEOF(destination)-1,destination)
SHL(destination,1)
BIT(0,destination) CF
n n - 1
ENDWHILE
IF count = 1 THEN
IF BIT(8*SIZEOF(destination)-1,destination) = CF THEN
OF 0
ELSE
OF 1
ENDIF
ELSE
OF undefined
ENDIF
┌────────────────────┐
┌────┐ │ ┌─────────────┐ │
│ CF ├──┴──┤ Destination ├──┘
└────┘ └─────────────┘
This instruction rotates the bits in the destination operand to the
left by 1 and repeats the process the number of times specified by count.
On each rotate, the value shifted out of the high bit is stored in the
carry flag and is shifted into the low bit of the result. For rotates
with a count of 1, the overflow flag is set if the high bit's value
changed and cleared otherwise. The overflow flag is undefined for rotates
with a count greater than 1.
Note that the 8086 and 8088 processors allow count values up to 255.
However, rotates never need to have count values greater than 15 (7 for
byte destinations, 31 for doublewords). Larger count values are
unnecessary since bits will be rotated completely around the operand and
back to their starting positions. The 80286 and later processors limit
the effective count to 31 by using only the low 5 bits of the specified
count. This was done to limit the amount of time that a pending interrupt
will have to wait for the processor to complete an instruction. The fact
that the count is limited will have no affect on the result of shift
instructions or on rotates that don't use the carry flag. However,
rotates through the carry with counts greater than 31 will produce
different results on processors that limit the count.
Note that the rotate by an immediate count instructions were added to
the instruction set with the 80186 processor. However, on some processors
it is faster to perform multiple single-bit rotates than a single
multi-bit rotate.
┌────────────────────────────────────────────────────────────────────────┐
│ 1101 000,w mod,000,r/m 0, 2, or 4 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ ROL reg,1 │ ROL AX,1 │ 88/86 2 │
│ │ │ 286 2 │
│ │ │ 386 3 │
│ │ │ 486 3 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ ROL mem,1 │ ROL MEMWRD,1 │ 88/86 15+EA │
│ │ │ WD88 23+EA │
│ │ │ 286 7 │
│ │ │ 386 7 │
│ │ │ 486 4 │
│ │ │ Pentm 3 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 1101 001,w mod,000,r/m 0, 2, or 4 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ ROL reg,CL │ ROL CH,CL │ 88/86 8+4n │
│ │ │ 286 5+n │
│ │ │ 386 3 │
│ │ │ 486 3 │
│ │ │ Pentm 4 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ ROL mem,CL │ ROL BYTE PTR [DI],CL │ 88/86 20+EA+4n │
│ │ │ WD88 28+EA+4n │
│ │ │ 286 8+n │
│ │ │ 386 7 │
│ │ │ 486 4 │
│ │ │ Pentm 4 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 1100 000,w mod,000,r/m 0, 2, or 4 byte displacement │
│ 1 byte immediate date │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ ROL reg,immed8 │ ROL EAX,5 │ 88/86 N/A │
│ │ │ 286 5+n │
│ │ │ 386 3 │
│ │ │ 486 2 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ ROL mem,immed │ ROL WORD PTR [BX],2 │ 88/86 N/A │
│ │ │ 286 8+n │
│ │ │ 386 7 │
│ │ │ 486 4 │
│ │ │ Pentm 3 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
SBB Subtract with Borrow Flags: O D I T S Z A P C
* * * * * *
SYNTAX:
SBB destination,source
LOGIC:
IF CF = 1 THEN
destination destination - source - 1
ELSE
destination destination - source
ENDIF
This instruction subtracts the source operand and the value of the
carry flag from the destination operand and stores the result in the
destination operand. This is usually used to perform "multi-element
subtraction" in order to subtract quantities that are larger than the
largest operand supported by the processor.
In a multi-element subtraction, the quantities are subtracted using
multiple subtraction operations that start with the least significant
portion (byte, word or doubleword) of the quantities and proceed to the
most significant portion. The first subtraction is performed with a
regular SUB instruction (or SBB if the carry flag is previously cleared)
and the remaining subtractions use the SBB instruction. Note: the
quantities to be subtracted can be either signed or unsigned.
EXAMPLE
This example subtracts the 32 bit number in CX:BX from the 32 bit
number in DX:AX and stores the result in DX:AX.
SUB AX,BX ; Subtract least significant word.
SBB DX,CX ; Subtract most significant word with borrow.
This example performs a multi-element subtraction of two operands
specified by pointers in SI and DI and whose length is specified in CX.
This example relies on the fact that when SI is adjusted with an INC
instruction, the carry flag is not affected. This is probably the main
reason that INC and DEC do not update the carry flag.
CLC ; Clear carry for first subtraction.
SUBTOP: MOV AL,[DI] ; Get next destination byte.
SBB AL,[SI] ; Subtract off next source byte.
STOSB ; Store result
INC SI ; Point to next source byte.
LOOP SUBTOP ; Loop back for next byte, if any.
Another use for the SBB instruction is negate boolean values. If
boolean values are represented using the C system that 0 is true and
non-zero is false, then the following code can be used to negate boolean
values without using branches (jumps).
CMP FLAG,1 ; Set carry if flag is false.
SBB AL,AL ; Set AL to value of carry.
MOV FLAG,AL ; Save inverted flag.
This code works follows as follows. The flag is compared to 1. This will
set the carry only if the flag was false (0). Then a register is
subtracted from itself with SBB. Regardless of the previous contents of
the register, this will yield 0 (false) if the carry is clear and -1 if
the carry was set. Thus it yields a boolean value opposite the one
tested. Note that in C (and many other languages) any non-zero value will
be treated as true, but logical operations will always return true as -1.
This code follows that practice.
┌────────────────────────────────────────────────────────────────────────┐
│ 0001 10,d,w mod,reg,r/m 0, 2, or 4 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ SBB reg,reg │ SBB DX,CX │ 88/86 3 │
│ │ │ 286 2 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ SBB mem,reg │ SBB NUMBER,CL │ 88/86 16+EA │
│ │ │ WD88 24+EA │
│ │ │ 286 7 │
│ │ │ 386 6 │
│ │ │ 486 3 │
│ │ │ Pentm 3 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ SBB reg,mem │ SBB CL,NUMBER │ 88/86 9+EA │
│ │ │ WD88 13+EA │
│ │ │ 286 7 │
│ │ │ 386 7 │
│ │ │ 486 2 │
│ │ │ Pentm 2 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 1000 00,s,w mod,011,r/m 0, 2, or 4 byte displacement │
│ 1, 2, or 4 byte immediate data │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ SBB reg,immed │ SBB BX,1992 │ 88/86 4 │
│ │ │ 286 3 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ SBB mem,immed │ SBB NUMBER,DX │ 88/86 17+EA │
│ │ │ WD88 25+EA │
│ │ │ 286 7 │
│ │ │ 386 7 │
│ │ │ 486 3 │
│ │ │ Pentm 3 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 0001 110,w 1, 2, or 4 byte immediate data │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ SBB accum,immed │ SBB AX,1992 │ 88/86 4 │
│ │ │ 286 3 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
TEST Test Flags: O D I T S Z A P C
0 * * ? * 0
SYNTAX:
TEST destination,source
LOGIC:
Flags set according to result of destination && source
This instruction, performs a bitwise logical AND operation on its
operands and sets the flags from the result. Unlike the AND instruction,
the result is discarded and neither operand is changed by this
instruction. This operation is frequently used to determine if a
particular bit in a bitfield is set. It can also be used to test if a
group of bits in a bitfield value is clear.
The TEST mem,reg instruction is not supported by the processor,
however, most assemblers will assemble the instruction by transposing the
operands and coding a TEST reg,mem instruction instead. Since the logical
AND operation is communitive and the result is not saved in either
operand, this produces the same results.
EXAMPLE
This example determines if bit 2 of CL is set. CL is TESTed with a
mask that has only bit 2 set. If the result is non-zero, the bit was
set, otherwise the bit was clear.
TEST CL,00000100Y ; AND value with mask.
JNZ BITSET ; If bit was set, branch around.
; Continue here if not set.
EXAMPLE
This example determines if the odd bits of a byte in memory are
clear. The byte is TESTed with a mask that has only the odd bits set. If
the result is zero, all the odd bits were clear, otherwise at least one
odd bit was set.
TEST BYTE PTR [BX],10101010Y ; AND value with mask.
JZ BITCLR ; If bits were clear, branch around.
; Continue here if any bits were set.
┌────────────────────────────────────────────────────────────────────────┐
│ 1000 010w mod,reg,r/m 0, 2, or 4 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ TEST reg,reg │ TEST DX,CX │ 88/86 3 │
│ │ │ 286 2 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ TEST mem,reg │ TEST NUMBER,CL │ 88/86 9+EA │
│ Instruction not │ │ WD88 13+EA │
│ really available │ │ 286 6 │
│ │ │ 386 5 │
│ │ │ 486 2 │
│ │ │ Pentm 2 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ TEST reg,mem │ TEST CL,NUMBER │ 88/86 9+EA │
│ │ │ WD88 13+EA │
│ │ │ 286 6 │
│ │ │ 386 5 │
│ │ │ 486 2 │
│ │ │ Pentm 2 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 1111 011,w mod,000,r/m 0, 2, or 4 byte displacement │
│ 1, 2, or 4 byte immediate data │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ TEST reg,immed │ TEST BX,1992 │ 88/86 5 │
│ │ │ 286 3 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ TEST mem,immed │ TEST NUMBER,DX │ 88/86 11+EA │
│ │ │ WD88 11+EA │
│ │ │ 286 6 │
│ │ │ 386 5 │
│ │ │ 486 2 │
│ │ │ Pentm 2 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 1010 100,w 1, 2, or 4 byte immediate data │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ TEST accum,immed │ TEST AX,1992 │ 88/86 4 │
│ │ │ 286 3 │
│ │ │ 386 2 │
│ │ │ 486 1 │
│ │ │ Pentm 1 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
VERR Verify Read Flags: O D I T S Z A P C
*
SYNTAX:
VERR selector
LOGIC:
IF selector is valid AND selector's segment is accessible at
the current privilege level AND selector's segment is readable THEN
ZF 1
ELSE
ZF 0
ENDIF
This instruction tests a selector to determine if it can be used
without causing a general protection fault. The instruction performs the
same tests that the processor would if the selector were loaded into a
data segment register (DS, ES, FS, or GS). If any of the tests detect an
error, the zero flag is cleared, otherwise the zero flag is set. This
instruction can be used to test a selector passed to a routine to make
sure that the selector can be used without causing a general protection
fault. This allows the routine to detect the error before it occurs and
to exit gracefully.
The instruction performs the following tests. It checks that the
selector is for a descriptor that is within the bounds of the appropriate
descriptor table (either the Global Descriptor Table (GDT) or the Local
Descriptor Table (LDT)). Then, it checks that the descriptor is for a
readable code or data segment. Finally, if the segment is not a
conforming code segment, the instruction checks that the segment's
Descriptor Privilege Level (DPL) is not more privileged (not numerically
less) than either the Current Privilege Level (CPL) or the selector's
Requester Privilege Level (RPL).
This instruction is available only when the processor is operating in
protected mode.
There is a bug in this instruction on some versions of the 80386. If
there are no JMP or CALL instructions or instructions with memory operands
in the instruction prefetch queue after the VERR, the processor will hang
until an external interrupt occurs. After the interrupt is handled
execution will continue after the VERR instruction. In most cases, the
system timer interrupt will unhang the processor. To avoid this problem,
however, a jump can be encoded after each VERR instruction. For example,
VERR AX ; Verify selector.
JMP $+2 ; Jump to next instruction.
; Execution continues here.
┌────────────────────────────────────────────────────────────────────────┐
│ 0000 1111 0000 0000 mod,100,r/m 0, 2, or 4 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ VERR reg16 │ VERR AX │ 88/86 N/A │
│ │ │ 286 14 │
│ │ │ 386 10 │
│ │ │ 486 11 │
│ │ │ Pentm 7 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ VERR mem16 │ VERR WORD PTR [BX] │ 88/86 N/A │
│ │ │ 286 16 │
│ │ │ 386 11 │
│ │ │ 486 11 │
│ │ │ Pentm 7 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
WAIT Wait Flags: O D I T S Z A P C
SYNTAX:
WAIT
LOGIC:
REPEAT
UNTIL external TEST line is active
This instruction can be used in a multiprocessor in environment to
synchronize operation performed between processors. The instruction can
be used to suspend processing on a processor until another processor has
completed a task.
┌────────────────────────────────────────────────────────────────────────┐
│ 1001 1011 │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ WAIT │ WAIT │ 88/86 3 │
│ │ │ 286 3 │
│ │ │ 386 6 │
│ │ │ 486 1-3 │
│ │ │ Pentm 1 │
└─────────────────────┴────────────────────────┴─────────────────────────┘
───────────────────────────────────────────────────────────────────────────────
XCHG Exchange Registers Flags: O D I T S Z A P C
SYNTAX:
XCHG destination,source
LOGIC:
destination source
This instruction exchanges the value the stored in the destination
operand with the value stored in the source operand. Neither value is
lost by this operation. Each value ends up where the other one was
stored. One of the operands must be a general purpose register, the other
operand may be a register or a memory location and must be of the same
size.
If one of the operands is a memory location, the instruction must be
encoded so that the memory location is the source the operand. However,
most assemblers will allow a memory location to be specified in the
destination, if the source is a register. The assembler will simply
encode the instruction with the operands reversed, which produces the same
results.
Since the exchange memory and register operation (XCHG reg,mem) is
often used to simultaneously test and set flags in a multi-processor
environment, the processor automatically asserts the lock signal (on 80286
and later processors) for this instruction so, a lock prefix is
unnecessary.
EXAMPLE
This example uses an exchange instruction to simultaneously test and
lock a flag in memory. This is often performed in multi-processor
environments, when flags in memory are used to control access to
resources. In the example, a memory location contains a flag that is -1
when the resource is being used by a processor and is 0 when the resource
is not being used. The processor exchanges the flag with a register
containing a -1. This insures that the flag will be -1 after the
exchange. If the register is 0 after the exchange, then the resource was
not being used, but is now being used by the current processor. If the
register is -1, then the resource is being used by a different processor.
Since the XCHG instruction automatically asserts the LOCK signal when one
of the operands is a memory location, this instruction cannot be performed
simultaneously by two processors. This prevents two processors from
locking the flag simultaneously.
MOV AL,-1 ; Load AL with locked value
LCKRESTOP: XCHG AL,FLGBYT ; Get the flag.
CMP AL,-1 ; Is resource in use?
JZ LCKRESTOP ; Yes, loop back to try again.
* * *
MOV FLGBYT,0 ; Release the resource.
┌────────────────────────────────────────────────────────────────────────┐
│ 1000 011,w mod,reg,r/m 0, 2, or 4 byte displacement │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ XCHG reg,reg │ XCHG AX,SI │ 88/86 4 │
│ │ │ 286 3 │
│ │ │ 386 3 │
│ │ │ 486 3 │
│ │ │ Pentm 3 │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ XCHG reg,mem │ XCHG AL,[DI] │ 88/86 17+EA │
│ │ │ WD88 25+EA │
│ │ │ 286 5 │
│ │ │ 386 5 │
│ │ │ 486 5 │
│ │ │ Pentm 3 │
├─────────────────────┴────────────────────────┴─────────────────────────┤
│ 1001 0,reg │
├─────────────────────┬────────────────────────┬─────────────────────────┤
│ XCHG accum,reg16 │ XCHG AX,BX │ 88/86 3 │
│ XCHG accum,reg32 │ │ 286 3 │
│ │ │ 386 3 │
│ │ │ 486 3 │
│ │ │ Pentm 2 │
└─────────────────────┴────────────────────────┴─────────────────────────┘